package com.witmore.neutron.ai.web.service.impl;

import com.alibaba.fastjson2.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jk.common.response.ResponseResult;
import com.witmore.neutron.ai.api.dto.ContentDTO;
import com.witmore.neutron.ai.api.dto.MessageContentDTO;
import com.witmore.neutron.ai.cognitive.dto.SessionDeductionRequest;
import com.witmore.neutron.ai.cognitive.service.UserSessionUsageService;
import com.witmore.neutron.ai.db.entity.AgentDO;
import com.witmore.neutron.ai.db.entity.AgentPublishConfigDO;
import com.witmore.neutron.ai.db.entity.ModelConfigDO;
import com.witmore.neutron.ai.db.entity.UserKeyDO;
import com.witmore.neutron.ai.db.mapper.AgentMapper;
import com.witmore.neutron.ai.db.mapper.AgentPublishConfigMapper;
import com.witmore.neutron.ai.db.mapper.ModelConfigMapper;
import com.witmore.neutron.ai.db.mapper.UserKeyMapper;
import com.witmore.neutron.ai.web.controller.bo.MessageBO;
import com.witmore.neutron.ai.web.controller.vo.ApiChatCompletionRequest;
import com.witmore.neutron.ai.web.enums.ShowFlagEnum;
import com.witmore.neutron.ai.web.service.ApiAgentService;
import com.witmore.neutron.ai.web.service.ChatClientRouterService;
import com.witmore.neutron.ai.web.utils.JsonArrayCheck;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 豆子高
 * @date 2025-05-26 14:23
 */
@Slf4j
@Service
public class ApiAgentServiceImpl implements ApiAgentService {

    @Autowired
    private ChatClientRouterService chatClientRouterService;
    @Autowired
    private AgentMapper agentMapper;
    @Autowired
    private AgentPublishConfigMapper agentPublishConfigMapper;
    @Autowired
    private UserKeyMapper userKeyMapper;

    @Autowired
    private UserSessionUsageService userSessionUsageService;
    @Autowired
    private ModelConfigMapper modelConfigMapper;

    @Override
    public ResponseResult<String> chatNew(HttpServletRequest request, ApiChatCompletionRequest req) {
        // 校验权限 从header中获取 token
        String publishKey = request.getHeader("Authorization");
        if (StringUtils.isEmpty(publishKey)) {
            return ResponseResult.fail(400, "token is empty");
        }
        // 根据publishKey查询用户信息
        UserKeyDO userKeyDO = userKeyMapper.selectOne(new LambdaQueryWrapper<UserKeyDO>()
                .eq(UserKeyDO::getApiKey, publishKey)
                .eq(UserKeyDO::getActiveStatus, 1)
                .last("LIMIT 1"));
        if (userKeyDO == null) {
            return ResponseResult.fail(400, "token is invalid");
        }
        // 校验智能体信息
        AgentDO agentDO = agentMapper.selectOne(new LambdaQueryWrapper<AgentDO>()
                .eq(AgentDO::getAgentCode, req.getAgentCode())
        );
        if (agentDO == null) {
            return ResponseResult.fail(1001, "机器人不存在");
        }
        // 发布信息
        AgentPublishConfigDO agentPublishConfigDO = agentPublishConfigMapper.selectOne(new LambdaQueryWrapper<AgentPublishConfigDO>()
                .eq(AgentPublishConfigDO::getAgentId, agentDO.getId())
                .eq(AgentPublishConfigDO::getAgentCode, req.getAgentCode())
                .eq(AgentPublishConfigDO::getPublishType, 1)
        );
        if (agentPublishConfigDO == null) {
            return ResponseResult.fail(1002, "机器人发布信息错误");
        }
        if (agentPublishConfigDO.getPublishStatus() == 0) {
            return ResponseResult.fail(1002, "机器人未发布");
        }

        ModelConfigDO modelConfigDO = modelConfigMapper.selectById(agentDO.getAiModelId());

        // 先校验次数
        SessionDeductionRequest sessionRequest = SessionDeductionRequest.of(userKeyDO.getUserId().intValue(), modelConfigDO, req.getSessionId());
        boolean checked = userSessionUsageService.checkUserSessionCount(sessionRequest);
        if (!checked) {
            return ResponseResult.fail(1003, "会话次数不足，请充值后再试");
        }
        MessageBO messageBO = new MessageBO();
        messageBO.setAgentId(agentDO.getId());
        messageBO.setAgentCode(req.getAgentCode());
        messageBO.setSource(req.getSource());
        messageBO.setStream(req.getStream());
        messageBO.setSessionId(req.getSessionId());
        messageBO.setUserApiKey(publishKey);
        messageBO.setUserId(userKeyDO.getUserId().intValue());
        List<MessageContentDTO> messages = new ArrayList<>();


        // 消息组装 TODO  目前就按照当前项目现有的内容进行组装
        req.getMessages().forEach(messageApiBO -> {
            if (!req.getSysPromptOverride()) {
                // 不覆盖 使用原有系统提示
                messages.add(new MessageContentDTO("system", agentDO.getAiSysPromptText(), ShowFlagEnum.NOT_SHOW.getCode()));
            } else {
                // 使用新的系统提示
                if (messageApiBO.getRole().equals("system")) {
                    messages.add(new MessageContentDTO("system", messageApiBO.getContent(), ShowFlagEnum.NOT_SHOW.getCode()));
                }
            }
            if (messageApiBO.getRole().equalsIgnoreCase("user")) {
                // 校验内容是否为json数组
                if (JsonArrayCheck.isJsonArray(messageApiBO.getContent())) {
                    MessageContentDTO messageContentDTO = new MessageContentDTO();
                    messageContentDTO.setRole("user");
                    messageContentDTO.setContent(messageApiBO.getContent());
                    messageContentDTO.setShowFlag(ShowFlagEnum.SHOW.getCode());
                    messages.add(messageContentDTO);
                } else {
                    // 不是json串，直接返回错误
                    throw new IllegalArgumentException("Invalid request: user message content must be a JSON array");
                }
            }
        });
        messageBO.setMessages(messages);
        ResponseResult<?> responseResult = chatClientRouterService.routeRequest(messageBO);
        if (responseResult != null && responseResult.getCode() == 200) {
            String content = (String) responseResult.getData();

            // 第二步  将结果进行解析
            // 根据传入的 返回类型再次调用大模型
            if (req.getResponseType().equals("json")) {
                // 校验用户输出格式提示词 都没设置的话 直接返回
                if (StringUtils.isEmpty(req.getResponseFormatPrompt()) && StringUtils.isEmpty(agentPublishConfigDO.getResponseFormatPrompt())) {
                    return ResponseResult.success(content);
                }
                // 优先取api接口自定义的设置
                String responseFormatPrompt = StringUtils.isEmpty(req.getResponseFormatPrompt()) ? agentPublishConfigDO.getResponseFormatPrompt() : req.getResponseFormatPrompt();
                List<MessageContentDTO> messagesResponseType = new ArrayList<>();
                messagesResponseType.add(new MessageContentDTO("system", "你是一个输出格式转换助手，请将用户发送给你的内容按照JSON格式输出。不要用Markdown代码格式包裹", ShowFlagEnum.NOT_SHOW.getCode()));
                // 用户提示词
                List<ContentDTO> contentDTOS = List.of(new ContentDTO("text", content, null), new ContentDTO("text", responseFormatPrompt, null));
                messagesResponseType.add(new MessageContentDTO("user", JSONArray.toJSONString(contentDTOS), ShowFlagEnum.NOT_SHOW.getCode()));
                messageBO.setMessages(messagesResponseType);
                ResponseResult<?> responseTypeResult = chatClientRouterService.routeRequest(messageBO);
                if (responseTypeResult != null && responseTypeResult.getCode() == 200) {
                    String content2 = (String) responseTypeResult.getData();
                    return ResponseResult.success(content2);
                }
                log.error("Chat request failed: {}", responseTypeResult);
                return ResponseResult.fail(500, "Chat request failed");
            }
            // TODO 以后有别的再进行优化

            return ResponseResult.success(content);
        } else {
            log.error("Chat request failed: {}", responseResult);
            return ResponseResult.fail(500, "Chat request failed");
        }


    }
}
